using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SolarWinds.Shapes
{
    public class CoordSystemShape : Shape
    {
        private VertexBuffer mVertexBuffer;
        private VertexDeclaration mVertexDeclaration;
        private IndexBuffer mIndexBuffer;
        private BasicEffect mBasicEffect;

        public CoordSystemShape(Game game) : base(game)
        {
        }

        public override void  Draw(GameTime gameTime)
        {
 	        base.Draw(gameTime);

            GraphicsDevice device = Game.GraphicsDevice;

            device.Vertices[0].SetSource(mVertexBuffer, 0, VertexPositionColor.SizeInBytes);
            device.VertexDeclaration = mVertexDeclaration;
            device.Indices = mIndexBuffer;
            device.RenderState.PointSize = 5;

            // set effect parameters
            mBasicEffect.World = World;
            mBasicEffect.View = View;
            mBasicEffect.Projection = Projection;
            mBasicEffect.DiffuseColor = Color.White.ToVector3();
            mBasicEffect.LightingEnabled = false;
            mBasicEffect.CommitChanges();
            
            mBasicEffect.Begin();
            foreach (EffectPass pass in mBasicEffect.CurrentTechnique.Passes)
            {
                pass.Begin();

                // x-axis
                mBasicEffect.DiffuseColor = Color.Red.ToVector3();
                mBasicEffect.CommitChanges();
                device.DrawPrimitives(PrimitiveType.LineList, 0, 1);
                device.DrawPrimitives(PrimitiveType.PointList, 1, 1);

                // y-axis
                mBasicEffect.DiffuseColor = Color.Green.ToVector3();
                mBasicEffect.CommitChanges();
                device.DrawPrimitives(PrimitiveType.LineList, 2, 1);
                device.DrawPrimitives(PrimitiveType.PointList, 3, 1);

                // z-axis
                mBasicEffect.DiffuseColor = Color.Blue.ToVector3();
                mBasicEffect.CommitChanges();
                device.DrawPrimitives(PrimitiveType.LineList, 4, 1);
                device.DrawPrimitives(PrimitiveType.PointList, 5, 1);

                pass.End();
            }
            mBasicEffect.End();
        }

        protected override void LoadContent()
        {
            GraphicsDevice device = Game.GraphicsDevice;

            mVertexBuffer = new VertexBuffer(device, typeof(VertexPositionColor), 6, BufferUsage.WriteOnly);
            var data = new VertexPositionColor[6];

            // x-axis
            data[0].Position = Vector3.Zero;
            data[0].Color = Color.Yellow;
            data[1].Position = Vector3.UnitX;
            data[1].Color = Color.Yellow;

            // y-axis
            data[2].Position = Vector3.Zero;
            data[2].Color = Color.Yellow;
            data[3].Position = Vector3.UnitY;
            data[3].Color = Color.Yellow;

            // z-axis
            data[4].Position = Vector3.Zero;
            data[4].Color = Color.Yellow;
            data[5].Position = Vector3.UnitZ;
            data[5].Color = Color.Yellow;

            mVertexBuffer.SetData(data);

            mVertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);

            mBasicEffect = new BasicEffect(device, null);
            mBasicEffect.EnableDefaultLighting();

            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();

            if (mVertexBuffer != null)
            {
                mVertexBuffer.Dispose();
                mVertexBuffer = null;
            }

            if (mVertexDeclaration != null)
            {
                mVertexDeclaration.Dispose();
                mVertexDeclaration = null;
            }

            if (mIndexBuffer != null)
            {
                mIndexBuffer.Dispose();
                mIndexBuffer = null;
            }

            if (mBasicEffect != null)
            {
                mBasicEffect.Dispose();
                mBasicEffect = null;
            }
        }

        protected override BoundingSphere UpdateBoundingSphere()
        {
            return new BoundingSphere(Vector3.Zero, 1.0f);
        }

        protected override BoundingBox UpdateBoundingBox()
        {
            return new BoundingBox(Vector3.Zero, Vector3.One);
        }
    }
}